<!--
<script setup lang="ts">
import type { UploadChangeParam, UploadProps } from 'ant-design-vue';

import { useAccessStore } from '@vben/stores';
import { isString } from '@vben/utils';

import { Button, message, Upload } from 'ant-design-vue';

import { baseUrlApi } from '#/api/request';
import { postUpload } from '#/api/system';
import Icon from '#/components/Icons';
import { usePreferencesStore } from '#/store';
import { formatFilePath } from '#/utils';

defineOptions({
  name: 'CustomUpload',
});

const props = withDefaults(
  defineProps<{
    modelValue?: any;
    multiple?: boolean;
    name?: string;
    returnstr?: boolean;
    showbox?: boolean;
    type?: 'audio' | 'file' | 'image' | 'photo' | 'video';
    ucClass?: string;
  }>(),
  {
    multiple: false,
    showbox: true,
    returnstr: false,
    type: 'image',
    modelValue: '',
    name: '',
    ucClass: 'upload-content',
  },
);

const emit = defineEmits<{
  (e: 'update:modelValue', data: any): void;
}>();

const accessStore = useAccessStore();
const uploadRef = ref<UploadProps>();
const state: any = reactive({
  accept: '.jpg,.jpeg,.png,.gif,.bmp4',
  limit: 50,
  size: 1,
  action: `${baseUrlApi('/user/upload/one')}`,
  headers: {},
  fileList: [],
  picture: 'picture',
  data: {},
  extensions: '',
  imgList: [],
  uploadedFiles: [], // 新增字段来跟踪已上传的文件
});
const listtype: any = ref('picture-card');
const imageUrl = ref('');
watch(
  () => props.modelValue,
  (value) => {
    if (value) {
      state.uploadedFiles = [];
      state.fileList = [];
      imageUrl.value =
        !props.multiple && isString(props.modelValue)
          ? formatFilePath(props.modelValue)
          : '';
      if (props.multiple && props.modelValue) {
        props.modelValue.forEach((element: any) => {
          if (isString(element)) {
            state.fileList.push({
              name: element.split('/').pop(),
              path: element,
              url: formatFilePath(element),
            });
            state.uploadedFiles.push(element);
          }
        });
      }
    }
  },
  {
    deep: true,
    immediate: true,
  },
);

function formatFileExtensions(fileFormats: string): string {
  const formatsArray = fileFormats
    .split(',')
    .map((format) => `.${format.trim()}`);
  return formatsArray.join(',');
}
const uploadSetting = async () => {
  const fileType = props.type === 'photo' ? 'image' : props.type;
  if (fileType !== 'image') {
    state.uclass = '';
    listtype.value = 'text';
  }
  const setting = await usePreferencesStore().getUploadSetting();
  const fileSetting = setting.file_types[fileType];
  const accept = formatFileExtensions(fileSetting.extensions);

  state.size = fileSetting.upload_max_filesize / 1024;
  state.accept = accept;
};

const beforeUpload: UploadProps['beforeUpload'] = (rawFile: any) => {
  if (rawFile.size / 1024 / 1024 > state.size) {
    message.error(`文件大小必须小于${state.size}!`);
    return false;
  }

  return true;
};

const httpRequest = async (options: any) => {
  options.data.filetype = props.type;

  try {
    const { data } = await postUpload(options);
    if (props.multiple) {
      const newFile = {
        name: data.filename,
        path: data.filepath,
        url: data.url,
      };
      state.uploadedFiles.push(newFile.path);
      const existingFileIndex = state.fileList.findIndex(
        (item: any) => item.path === newFile.path,
      );
      if (existingFileIndex !== -1) {
        state.fileList.splice(existingFileIndex, 1);
        return;
      }
      state.fileList.push(newFile);
      if (state.uploadedFiles.length === state.fileList.length) {
        emit('update:modelValue', state.uploadedFiles);
      }
    } else {
      imageUrl.value = data.url;
      emit('update:modelValue', data.filepath);
    }
  } catch {
    // onError(error);
  }
};

const handleRemove: UploadProps['onRemove'] = (uploadFile: any) => {
  if (state.uploadedFiles.length > 0) {
    const existingFileIndex = state.uploadedFiles.indexOf(uploadFile.path);
    if (existingFileIndex !== -1) {
      state.uploadedFiles.splice(existingFileIndex, 1);
    }
    emit('update:modelValue', state.uploadedFiles);
  }
};

const handleUploadChange = (info: UploadChangeParam) => {
  const { status } = info.file;
  if (status === 'done') {
    message.success(`${info.file.name} 文件上传成功`);
    if (state.uploadedFiles.length === info.fileList.length) {
      emit('update:modelValue', state.uploadedFiles);
    }
  } else if (status === 'error') {
    message.error(`${info.file.name} 文件上传失败`);
  }
};

onMounted(() => {
  const token = accessStore.accessToken;
  state.headers['XX-Token'] = token;
  state.headers.Authorization = token;
  state.headers['XX-Device-Type'] = 'web';
  uploadSetting();
});
</script>

<template>
  <div class="flex flex-col">
    <Upload
      ref="uploadRef"
      :accept="state.accept"
      :action="state.action"
      :before-upload="beforeUpload"
      :class="ucClass"
      :custom-request="httpRequest"
      :data="state.data"
      :file-list="state.fileList"
      :headers="state.headers"
      :limit="state.limit"
      :list-type="listtype"
      :multiple="multiple"
      :show-file-list="multiple"
      name="file"
      @change="handleUploadChange"
      @remove="handleRemove"
    >
      <template v-if="type !== 'image'">
        <span v-if="imageUrl" style="margin-right: 5px">{{ imageUrl }}</span>
        <Button type="primary">点击上传</Button>
      </template>
      <template v-else>
        <img v-if="imageUrl && !multiple" :src="imageUrl" class="avatar" />
        <span v-else class="avatar-uploader-icon">
          <Icon icon="ri:add-line" />
        </span>
      </template>
    </Upload>
    <p class="mt-2 text-sm text-red-600">
      小于{{ state.size }}MB的{{ state.accept }}文件
    </p>
  </div>
</template>
<style lang="scss" scoped>
.table-uploader {
  :deep(.ant-upload) {
    width: 40px !important;
    height: 40px !important;
  }
}
</style>
-->


<script setup lang="ts">
import type { UploadChangeParam, UploadProps } from 'ant-design-vue';

import { useAccessStore } from '@vben/stores';
import { isString } from '@vben/utils';

import { Button, message, Upload } from 'ant-design-vue';

import { baseUrlApi,UploadUrlApi } from '#/api/request';
import { postUpload } from '#/api/system';
import Icon from '#/components/Icons';
import { usePreferencesStore } from '#/store';
import { formatFilePath } from '#/utils';

defineOptions({
  name: 'CustomUpload',
});

const props = withDefaults(
  defineProps<{
    modelValue?: any;
    multiple?: boolean;
    name?: string;
    returnstr?: boolean;
    showbox?: boolean;
    type?: 'audio' | 'file' | 'image' | 'photo' | 'video';
    ucClass?: string;
  }>(),
  {
    multiple: false,
    showbox: true,
    returnstr: false,
    type: 'image',
    modelValue: '',
    name: '',
    ucClass: 'upload-content',
  },
);

const emit = defineEmits<{
  (e: 'update:modelValue', data: any): void;
}>();

const accessStore = useAccessStore();
const uploadRef = ref<UploadProps>();
const state: any = reactive({
  accept: '.jpg,.jpeg,.png,.gif,.bmp4',
  limit: 50,
  size: 1,
  action: `${UploadUrlApi('/user/upload/one')}`,
  headers: {},
  fileList: [],
  picture: 'picture',
  data: {},
  extensions: '',
  imgList: [],
  uploadedFiles: [], // 新增字段来跟踪已上传的文件
});
const listtype: any = ref('picture-card');
const imageUrl = ref('');
watch(
  () => props.modelValue,
  (value) => {
    if (value) {
      state.uploadedFiles = [];
      state.fileList = [];
      imageUrl.value =
        !props.multiple && isString(props.modelValue)
          ? formatFilePath(props.modelValue)
          : '';
      if (props.multiple && props.modelValue) {
        props.modelValue.forEach((element: any) => {
          if (isString(element)) {
            state.fileList.push({
              name: element.split('/').pop(),
              path: element,
              url: formatFilePath(element),
            });
            state.uploadedFiles.push(element);
          }
        });
      }
    }
  },
  {
    deep: true,
    immediate: true,
  },
);

function formatFileExtensions(fileFormats: string): string {
  const formatsArray = fileFormats
    .split(',')
    .map((format) => `.${format.trim()}`);
  return formatsArray.join(',');
}
const uploadSetting = async () => {
  const fileType = props.type === 'photo' ? 'image' : props.type;
  if (fileType !== 'image') {
    state.uclass = '';
    listtype.value = 'text';
  }
  const setting = await usePreferencesStore().getUploadSetting();
  const fileSetting = setting.file_types[fileType];
  const accept = formatFileExtensions(fileSetting.extensions);

  state.size = fileSetting.upload_max_filesize / 1024;
  state.accept = accept;
};

const beforeUpload: UploadProps['beforeUpload'] = (rawFile: any) => {
  if (rawFile.size / 1024 / 1024 > state.size) {
    message.error(`文件大小必须小于${state.size}!`);
    return false;
  }

  return true;
};

const httpRequest = async (options: any) => {
  options.data.filetype = props.type;

  try {
    const { data } = await postUpload(options);
    if (props.multiple) {
      const newFile = {
        name: data.filename,
        path: data.filepath,
        url: data.url,
      };
      state.uploadedFiles.push(newFile.path);
      const existingFileIndex = state.fileList.findIndex(
        (item: any) => item.path === newFile.path,
      );
      if (existingFileIndex !== -1) {
        state.fileList.splice(existingFileIndex, 1);
        return;
      }
      state.fileList.push(newFile);
      if (state.uploadedFiles.length === state.fileList.length) {
        emit('update:modelValue', state.uploadedFiles);
      }
    } else {
      imageUrl.value = data.url;
      emit('update:modelValue', data.filepath);
    }
  } catch {
    // onError(error);
  }
};

const handleRemove: UploadProps['onRemove'] = (uploadFile: any) => {
  if (state.uploadedFiles.length > 0) {
    const existingFileIndex = state.uploadedFiles.indexOf(uploadFile.path);
    if (existingFileIndex !== -1) {
      state.uploadedFiles.splice(existingFileIndex, 1);
    }
    emit('update:modelValue', state.uploadedFiles);
  }
};

const handleUploadChange = (info: UploadChangeParam) => {
  const { status } = info.file;
  if (status === 'done') {
    message.success(`${info.file.name} 文件上传成功`);
    if (state.uploadedFiles.length === info.fileList.length) {
      emit('update:modelValue', state.uploadedFiles);
    }
  } else if (status === 'error') {
    message.error(`${info.file.name} 文件上传失败`);
  }
};

onMounted(() => {
  const token = accessStore.accessToken;
  state.headers['XX-Token'] = token;
  state.headers.Authorization = token;
  state.headers['XX-Device-Type'] = 'web';
  uploadSetting();
});
</script>

<template>
  <div class="flex flex-col">
    <a-upload
      ref="uploadRef"
      :accept="state.accept"
      :action="state.action"
      :before-upload="beforeUpload"
      :class="ucClass"
      :custom-request="httpRequest"
      :data="state.data"
      :file-list="state.fileList"
      :headers="state.headers"
      :limit="state.limit"
      :list-type="listtype"
      :multiple="multiple"
      :show-file-list="multiple"
      name="file"
      @change="handleUploadChange"
      @remove="handleRemove"
    >
      
      <template >
        <img v-if="imageUrl && !multiple" :src="imageUrl" class="avatar" />
        <span v-else class="avatar-uploader-icon">
          <Icon icon="ri:add-line" />
        </span>
      </template>
    </a-upload>
   
  </div>
</template>
<style lang="scss" scoped>
.table-uploader {
  :deep(.ant-upload) {
    width: 40px !important;
    height: 40px !important;
  }
}
</style>